package org.wzh.spring.di.demo5;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.wzh.spring.di.demo1.CompactDisc;
import org.wzh.spring.di.demo1.SgtPeppers;
import org.wzh.spring.di.demo4.CDPlayer;

@Configuration
public class CDPlayerConfig {

	/**
	 * @Bean 注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean.
	 * 方法体中包含了最终产生bean实例的逻辑.
	 * 
	 * 默认情况下,bean的ID与带有@Bean注解的方法名是一样的.
	 * 如果想为其设置一个不同的名字的话,可以重命名该方法,也可以通过name属性指定一个不同的名字
	 * @return
	 */
	@Bean
	public CompactDisc sgtPeppers() {
		return new SgtPeppers();
	}
	
	@Bean(name="lonelyHeartsClubBand")
	public CompactDisc sgtPeppers2() {
		return new SgtPeppers();
	}

	/**
	 * 看起来,CompactDisc是通过调用sgtPeppers()得到的,但情况并非完全如此,因为sgtPeppers()方法
	 * 上添加了@Bean注解,Spring将会拦截所有对它的调用,并确保直接返回该方法所创建的bean,而不是每次都对其
	 * 进行实际的调用.
	 * @return
	 */
	@Bean
	public CDPlayer cdPlayer() {
		//public CDPlayer(CompactDisc cd)
		return new CDPlayer(sgtPeppers());
	}
	
	/**
	 * 在这里,cdPlayer()方法请求一个CompactDisc作为参数.当Spring调用cdPlayer()创建CDPlayer bean
	 * 的时候,它会自动装配一个CompactDisc到配置方法之中.然后,方法体就可以按照合十的方式来使用它.借助这种技术,
	 * cdPlayer()方法也能够将CompactDisc注入到CDPlayer的构造器中,而且不用明确引用CompactDisc的@Bean方法.
	 * 
	 * 通过这种方式引用其他的bean通常是最佳的选择,因为它不会要求将CompactDisc声明到同一个配置类之中.
	 * 在这里甚至没有要求CompactDisc必须要在JavaConfig中声明,实际上它可以通过组件扫描功能自动发现或者通过XML来进行配置.
	 * 你可以将配置分散到多个配置类,XML文件以及自动扫描和装配bean之中,只要功能完整健全即可.不管CompactDisc是采用什么方式创建
	 * 出来的,Spring都会将其传入到配置方法中,并用来创建CDPlayer bean.
	 * @param compactDisc
	 * @return
	 */
	@Bean
	public CDPlayer cdPlayer2(CompactDisc compactDisc) {
		return new CDPlayer(compactDisc);
	}
	
	@Bean
	public CDPlayer cdPlayer3(CompactDisc compactDisc) {
		CDPlayer cdPlayer = new CDPlayer(compactDisc);
		cdPlayer.setCd(compactDisc);
		return cdPlayer;
	}
}
